﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using XMLGener.Interfaces;
using XMLGener.Data;

namespace XMLGener.Utils
{
    /// <summary>
    /// 
    /// </summary>
    public class XMLGenerXSDConverter:XMLSchemeConverter
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="logger"></param>
        public XMLGenerXSDConverter(XLogger logger)
        {
            this.logger = logger;
        }
         
        private XLogger logger = null;
        /// <summary>
        /// 
        /// </summary>
        public Dictionary<string, XSDConverterNode> groupsDict = new Dictionary<string, XSDConverterNode>();
        
        private string shortFileName = "";
        private string mainElementName = "";
        private XSDConverterNode mainElement = null;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="doc"></param>
        /// <returns></returns>
        public bool generateScheme(XMLGenerDocument doc)
        {
            if (doc == null)
                return false;
            doc.preCalculate();
            TextWriter tw = null;
            /*try
            {*/
                FileInfo fi = new FileInfo(doc.outFileFullPath);
                if (fi.Extension == "")
                {
                    logger.addErrorLog(this.GetType().ToString(), "Output file is not defined correctly. File exstension is missing.");
                    return false;
                }
                String schName = fi.Name;
                shortFileName = schName.Replace(fi.Extension, ".xsd");
                schName = DirectoriesUtil.combinePath(fi.DirectoryName, shortFileName);
                tw = new StreamWriter(schName);


                this.mainElement =  new XSDConverterNode(doc.getMainElement(),this);
                this.mainElement.isMainElement = true;
                this.mainElementName = doc.getMainElement().name;
                Stack<XSDConverterNode> stack = new Stack<XSDConverterNode>();
                XSDConverterNode mainEl = mainElement;
                XSDConverterNode el = null;
                // create and initialize tree 
                stack.Push(mainEl);
               
                while (stack.Count > 0)
                {
                    el = stack.Peek();
                    if (el == null)
                        continue;
                    if (!el.childsInStack)
                    {
                        foreach (XSDConverterNode childEl in el.getChilds())
                        {
                            if (childEl != null)
                                stack.Push(childEl);
                        }
                        el.childsInStack = true;
                    }
                    else 
                    {
                        el.init();
                        stack.Pop();
                    }
                }

                // create definition document
                tw.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
                tw.WriteLine("<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">");

                StringBuilder sb = new StringBuilder();
                stack.Push(mainEl);
                while (stack.Count > 0)
                {
                    el = stack.Pop();
                    sb.Length = 0;
                    el.print(sb);
                    tw.WriteLine(sb.ToString());
                    foreach(XSDConverterNode childEl in el.getChilds())
                    {
                        if (childEl != null)
                            stack.Push(childEl);
                    }
                }


                tw.WriteLine("</xs:schema>");
           /*}
            catch (Exception e)
            {
                logger.addErrorLog(this.GetType().ToString(), e.Message);
                return false;
            }*/
            if (tw != null)
                tw.Close();

            return true;
        }

       

        

       
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public string getSchemaHeaderForXML()
        {

            StringBuilder sb = new StringBuilder();
            sb.Append("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"");
            sb.Append(shortFileName).Append("\" ");
            return sb.ToString();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool schemaHeaderIsDocumentAttribute()
        {
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public XMLGenerDocument parseDocument(string fileName)
        {
            throw new NotImplementedException();
        }

       
    }
}
